﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.TestManagement.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using Microsoft.TeamFoundation.Framework.Client;
using Microsoft.TeamFoundation.Framework.Common;
using System.Security.Cryptography;
using System.Reflection;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
using System.IO;
using System.Xml;

namespace TFSServerProvider
{
    public class TFSServerProvider
    {
        private string _tfsserverurl;
        public string TFSServerURL
        {
            get
            {
                return _tfsserverurl;
            }
        }

        private ITestManagementTeamProject _teamprojobj = null;
        public ITestManagementTeamProject TeamProjObj
        {
            get
            {
                return _teamprojobj;
            }
        }


        private List<Project> _projectobjs = new List<Project>();
        public List<Project> Projects
        {
            get
            {
                return _projectobjs;
            }
        }

        private bool _copyreferencefile = false;
        public bool CopyReferenceFile
        {
            get
            {
                return _copyreferencefile;
            }
            set
            {
                _copyreferencefile = value;
            }
        }
        private List<String> _copyreferencefiles;
        public List<String> CopyReferencefiles
        {
            get
            {
                return _copyreferencefiles;
            }
            set
            {
                _copyreferencefiles = value;
            }
        }

        private WorkItemStore _workItemStore = null;


        public TFSServerProvider(string tfsserverurl)
        {
            this._tfsserverurl = tfsserverurl;
            this._workItemStore = new WorkItemStore(this._tfsserverurl);
            _projectobjs.Clear();
            foreach (Project pr in this._workItemStore.Projects)
            {
                if (pr.HasWorkItemReadRights || pr.HasWorkItemReadRightsRecursive || pr.HasWorkItemWriteRights || pr.HasWorkItemWriteRightsRecursive)
                {
                    _projectobjs.Add(pr);
                }
            }
        }

        public Project GetProject(string projname)
        {
            Project rtnproj = null;
            foreach (Project proj in _projectobjs)
            {
                if (proj.Name.ToLower() == projname.ToLower())
                {
                    rtnproj = proj;
                    break;
                }
            }
            return rtnproj;
        }

        public QueryDefinition GetTeamQuery(Project proj, string queryname)
        {
            QueryDefinition rtnquery = null;
            foreach (QueryDefinition query in this.GetAllTeamQueries(proj))
            {
                if (query.Path.ToLower() == queryname.ToLower())
                {
                    rtnquery = query;
                    break;
                }
            }
            return rtnquery;

            
        }

        public IEnumerable<QueryDefinition> GetAllTeamQueries(Project proj)
        {
            QueryFolder queryFolder = proj.QueryHierarchy;
            return this.GetAllTeamQueries(queryFolder);
        }


        public NodeCollection GetIterationRootNodes(string projname)
        {
            Project proj = GetProject(projname);
            return proj.IterationRootNodes;

        }

        public WorkItemCollection GetItemFromQuery(QueryDefinition query)
        {
            string wiql = query.QueryText;
            if (query.Project != null)
                wiql = wiql.ToLower().Replace("@project","'"+query.Project.Name+"'");
            return this._workItemStore.Query(wiql);
        }

        private QueryDefinition GetQueryFromWiqFile(string wiqFilePath)
        {
            //XmlDocument wiq = new XmlDocument();
            //wiq.Load(wiqFilePath);
            FileInfo wiq = new FileInfo(wiqFilePath);
            //string TeamFoundationServer = "";
            string TeamProject = "";
            string Wiql = "";
            //TeamFoundationServer = ReadInfoXmlSingleNode(wiq, "/WorkItemQuery/TeamFoundationServer");
            TeamProject = MSCISDevMetricHelper.CommonHelper.ReadInfoXmlSingleNode(wiq, "/WorkItemQuery/TeamProject");
            Wiql = MSCISDevMetricHelper.CommonHelper.ReadInfoXmlSingleNode(wiq, "/WorkItemQuery/Wiql");
            Wiql = Wiql.ToLower().Replace("@project", "'" + TeamProject + "'").Replace("&gt;", ">").Replace("&lt;","<");
            QueryDefinition query = new QueryDefinition("BugList", Wiql);
            return query;
        }

        public DataTable GetItemFromQueryToDataTable(QueryDefinition query)
        {
            WorkItemCollection wic = GetItemFromQuery(query);
            DataTable dt = new DataTable("ItemList");
            for (int i = 0; i < wic.DisplayFields.Count; i++)
            {
                dt.Columns.Add(wic.DisplayFields[i].Name);
            }
            DataRow dr;
            for (int ii = 0; ii < wic.Count; ii++)
            {
                dr = dt.NewRow();
                for (int i = 0; i < wic.DisplayFields.Count; i++)
                {
                    dr[wic.DisplayFields[i].Name] = wic[ii][wic.DisplayFields[i].Name];
                }
                dt.Rows.Add(dr);
            }
                return dt;
        }

        public void GetItemFromQueryToFile(QueryDefinition query,string file)
        {
            FileInfo fi = new FileInfo(file);
            WorkItemCollection wic = GetItemFromQuery(query);
            if (fi.Exists)
                fi.Delete();
            StreamWriter sw = File.CreateText(fi.FullName);
            for (int i = 0; i < wic.DisplayFields.Count; i++)
            {
                sw.Write(wic.DisplayFields[i].Name);
                if (i < wic.DisplayFields.Count - 1)
                    sw.Write("|~|");
            }
            sw.WriteLine("\r");
            for (int ii = 0; ii < wic.Count; ii++)
            {
                for (int i = 0; i < wic.DisplayFields.Count; i++)
                {
                    sw.Write(wic[ii][wic.DisplayFields[i].Name]);
                    if (i < wic.DisplayFields.Count - 1)
                        sw.Write("|~|");
                }
                sw.WriteLine("\r");
            }
            sw.Close();
            sw.Dispose();
        }
        public DataTable GetItemFromQueryToDataTable(string projname, string queryname)
        {
            QueryDefinition query = GetTeamQuery(GetProject(projname), queryname);
            return GetItemFromQueryToDataTable(query);
        }

        public DataTable GetItemFromQueryScriptToDataTable(string queryScript)
        {
            QueryDefinition query = new QueryDefinition("BugList", queryScript);
            return GetItemFromQueryToDataTable(query);
        }

        public void GetItemFromQueryToFile(string projname, string queryname, string file)
        {
            QueryDefinition query = GetTeamQuery(GetProject(projname), queryname);
            GetItemFromQueryToFile(query, file);
        }


        private IEnumerable<QueryDefinition> GetAllTeamQueries(IEnumerable<QueryItem> queryFolder)
        {
            List<QueryDefinition> list = new List<QueryDefinition>();
            foreach (QueryItem item in queryFolder)
            {
                if (item is QueryFolder)
                {
                    list.AddRange(this.GetAllTeamQueries(item as QueryFolder));
                }
                else
                {
                    QueryDefinition _qd = item as QueryDefinition;
                    if (_qd.QueryType == QueryType.List)
                        list.Add(_qd);
                }
            }
            return list;
        }



        
    }

}
